6.3 Generators

Generators summarize two kinds of expressions: series and collections. A generator can be expanded into the expression it summarizes using Distribute . Individual elements of a collection generator can be extracted using indexing. Collection generators can serve as an indexable source in place of their expansion. For the syntax of generators, see §2.8.3.

6.3.1 Distribute

The result of expanding a series generator using Distribute is an expression consisting of operands joined by binary operators. The expansion of a collection generator is a set, a tuple or a matrix. A generator can only be expanded in this way if the limits are manifest expressions. Such generators are said to be iterable.

For example, the first few terms of Taylor's series for sin are given by ∑0, 3, -1^n⋅(x^(2⋅n+1)÷(2⋅n+1) !)ⅆn. After symbolic Distribute and algebraic Simplify , the expression becomes x÷1 !-x^3÷3 !+x^5÷5 !-x^7÷7 !.

Alternating series are also created by using ± as the operator in a generalized series. The Taylor's series shown above can be generated by (±|y∈(x^(2⋅n+1)÷(2⋅n+1) !|n∈0, 3)).

The result of expanding an iterable tuple generator is a tuple. The expansion of (x^i|i∈0, 3) is (x^0, x^1, x^2, x^3). The generator body can itself contain a tuple or any other kind of expression. The expansion of ((i, x^i)|i∈0, 3) is ((0, x^0), (1, x^1), (2, x^2), (3, x^3)).

A matrix generator expands into a matrix. [x^y|x∈0, 1|y∈0, 2] expands to [(0^0, 0^1, 0^2), (1^0, 1^1, 1^2)].

6.3.2 Manipulate

Simple series generators can be manipulated by left and right moves. For example, ∑1, 4, .{3}⋅n^2ⅆn and produce 3⋅∑1, 4, n^2ⅆn. ∏1, 4, .{a}⋅n^2ⅆn and produce (∏1, 4, aⅆn)⋅∏1, 4, n^2ⅆn.

6.3.3 Collections and Indexing

Indexing takes the form expression [ index ] and displays as expressionʈ[index]. The index can be a comma-separated list of expressions.

Ordered collections, along with their generators and iterators, are called indexable collections. Sets, and hence set generators, are not indexable collections because sets are not ordered. Scalars are not indexable because they are not collections. Thus only tuples and matrices are indexable collections. The general rule is that an indexed expression can be simplified if the expression is an indexable iterable collection and the index evaluates to a real constant, .

For example, the tuple and index expression (1, 3, 5, 7)[2] simplifies to 5. The same tuple can be generated and indexed by (2⋅i-1|i∈1, 4)[2]. An intermediate result can be displayed by selecting just the generator .{(2⋅i-1|i∈1, 4)}[2] and expanding it.

A similar example illustrates indexing for matrices. Note here the distinction between Mɱ[x], Mɱ[x, y] and Mɱ[x][y]. The latter form provides a way to simplify just the first dimension of a matrix, yielding an indexed array generator as a result. [(0, 1, 2), (3, 4, 5)][1] is (3, 4, 5). With a double index, [(0, 1, 2), (3, 4, 5)][1][2] is 5, as is [(0, 1, 2), (3, 4, 5)][1, 2] but .{[(0, 1, 2), (3, 4, 5)][1]}[2] is (3, 4, 5)[2].

The preceding examples uses numeric values and simplification to show the operation of indexing. The dimensions and indexes of matrices can also be represented by unbound variables. However, only Evaluate can be used to bind variables to other expressions on the display. In the presence of a=1, b=2, r=2 and c=3, The expression [c⋅x+y|x∈0, r-1|y∈0, c-1][a, b] evaluates to 5

6.3.4 Generators and Indexing

Like other constructs in Myron, indexing is dynamically applied. An expression like aɱ[1, 2, 3] cannot be evaluated until a is given a value either through substitution or binding. Because a is not known, the number of indexes cannot be known in advance. If the indexed expression is composed of many indexable items, the expression is reduced by applying indexes one at a time until either the result is a scalar or no indexes remain.

To illustrate, consider a matrix of tuples.

[((1, 2, 3), (2, 3, 4), (3, 4, 5)), ((2, 3, 4), (3, 4, 5), (4, 5, 6)), ((3, 4, 5), (4, 5, 6), (5, 6, 7))].

 


Applied to this matrix, the index [0,1,2] (or [0][1][2]) produces value 4. The first two indexes select the element in the 0th row and 1st column to produce the tuple (2, 3, 4). This tuple, indexed by 2, produces the value 4.

A more interesting example occurs when the same matrix is produced by indexing a generator.

[(i+r+c|i∈1, 3)|r∈0, 2|c∈0, 2][0][1][2].

 


The indexes have been separated so the effect of incremental simplification can be seen. Applied to the entire expression, the result is the same as if the index was [0,1,2]. But with the incremental indexes, simplifying the generator and the first index produces a tuple generator nested with a tuple generator: ((i+0+c|i∈1, 3)|c∈0, 2)[1][2]. Simplifying the expression and the first index again produces another tuple generator (i+0+1|i∈1, 3)[2]. Final simplification produces 3+0+1.